home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
UTILITIE
/
CONVERSI
/
0825C.ZIP
/
80TO86.ARC
/
80T86.ASM
next >
Wrap
Assembly Source File
|
1985-08-14
|
31KB
|
1,346 lines
; ------------------------------------------------------------
; Machine language translator - 8080 code to 8086 code
;
; 80T86 - Copyright (C) 1984
; Universidad Autonoma de Puebla
;
; [Harold V. McIntosh, 28 August 1984]
; ------------------------------------------------------------
bdos equ 0E0H
; -------------
org 005CH
FC80 rb 0 ;.ASM FCB
; -------------
tsiz equ 0080H
SZ86 equ 0080H ;size of .A86 buffer
SZ80 equ 0080H ;size of .ASM file buffer
; -------------
org 0080H
BU80 rb 0 ;.ASM buffer
; -------------
csiz equ 257 ;max chars in Huffman code
; Nongraphic characters.
HT equ 09H
LF equ 0AH
CR equ 0DH
; -------------
org 0100H
; -------------
begn: mov stak,sp ;save sp
mov al,FC80+1 ;.ASM FCB
cmp al,' '
jz G001 ! jmp ntut ! G001:
mov dx,(offset tuto)
ferm: call mssg
exit: mov sp,stak
mov dl,00
mov cl,00
int bdos
ntut: mov bx,(offset BU86) ;.A86 buffer
mov PT86,bx ;pointer to .A86 buffer
mov bx,(offset BU80) ;.ASM buffer
mov PT80,bx ;.ASM file index
mov cx,(offset 0021H) ;33 00's
mov bx,(offset FC86) ;.A86 FCB
call fiuc ;block fill
mov ch,8
mov dx,(offset FC80+1)
mov bx,(offset FC86+1)
call miuc
mov (byte ptr [bx]),'A'
pushf ! inc bx ! popf
mov (byte ptr [bx]),'8'
pushf ! inc bx ! popf
mov (byte ptr [bx]),'6'
xor al,al
mov FC80+32,al ;.ASM FCB
mov dens,al ;z/nz = un/squeezed
mov mult,al ;repeat factor
mov xait,al ;z/nz = character not/waiting
mov dx,(offset FC80) ;.ASM FCB
mov cl,15 ;(0F) open file
int bdos
inc al
jz G002 ! jmp opef ! G002:
mov dx,(offset nfil) ;'requested file not found'
jmp ferm ;final (error) message
opef: mov bx,(offset 0000)
mov CO80,bx
mov bx,(offset CO86) ;capaity of .A86 buffer
mov (byte ptr [bx]),SZ86+1 ;size of .A86 buffer
mov al,FC80+10
cmp al,'Q'
jz G003 ! jmp nsqz ! G003:
cota: call rbyt ;fetch one byte from input stream
cmp al,076H
jz G004 ! jmp nsqz ! G004:
call rbyt ;fetch one byte from input stream
cmp al,0FFH
jz G005 ! jmp nsqz ! G005:
; The "squeezed" marker is followed by a two-byte checksum,
; which is the simple sum of all the one-byte characters in
; the source file, carried as a two byte sum modulo 2**16.
rchk: call rwor ;fetch two bytes from input stream
mov cksm,bx ;checksum
; Unsqueezed file name. It is an ASCII sequence, may be lower
; case if SQ.COM received it in response to a prompt, ending
; with a zero byte.
luup: call rbyt ;fetch one byte from input stream
call cona
or al,al
jz G006 ! jmp luup ! G006:
; Load code dictionary. It is preceded by its two-byte length,
; and consists of a series of pairs of two-byte addresses. For
; each bit in the code, select the first element (0) or the
; second (1) element of the pair. If the pair is positive, it
; is the table entry (code + 4*index) at which to continue with
; the next bit. If the pair is negative, it is the complement
; of the coded ASCII character (low order byte except for [end]).
ldic: call rwor ;fetch two bytes from input stream
mov cx,(offset csiz)
mov al,cl
sub al,bl
mov al,ch
sbb al,bh
jc G007 ! jmp ldii ! G007:
mov dx,(offset ntab) ;'insufficient dictionary space'
jmp ferm ;final (error) message
ldii: add bx,bx
add bx,bx
mov cl,bl
mov ch,bh
mov dx,(offset code) ;decoding table
luuq: call rbyt ;fetch one byte from input stream
xchg dx,bx ! mov [bx],al ! xchg dx,bx
pushf ! inc dx ! popf
pushf ! dec cx ! popf
mov al,cl
or al,ch
jz G008 ! jmp luuq ! G008:
call crlf ;type CR,LF
mov bx,(offset roco)
mov (byte ptr [bx]),1
mov bx,(offset dens) ;z/nz = un/squeezed
mov (byte ptr [bx]),0FFH
nsqz: mov cl,26 ;(1A) set DMA address
mov dx,(offset BU86) ;.A86 buffer
int bdos
mov dx,(offset FC86) ;.A86 FCB
mov cl,17 ;(11) search for file
int bdos
inc al
jnz G009 ! jmp nexi ! G009:
mov dx,(offset yexi) ;'file already exists'
jmp ferm ;final (error) message
nexi: mov dx,(offset FC86) ;.A86 FCB
mov cl,22 ;(16) create file
int bdos
cmp al,0FFH
mov dx,(offset nodi) ;'no more directory'
jnz G010 ! jmp ferm ! G010: ;final (error) message
call cbuz ;clear output buffer to zeroes
; %-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%
runrun: call inch ;byte from input stream
call wrid ;byte to output stream
cmp al,CR
jnz G011 ! jmp runrun ! G011:
cmp al,LF
jnz G012 ! jmp runrun ! G012:
cmp al,1AH
jnz G013 ! jmp clof ! G013:
cmp al,';'
jz G014 ! jmp nosc ! G014:
yesc: call inch ;byte from input stream
call wrid ;byte to output stream
cmp al,LF
jnz G015 ! jmp runrun ! G015:
jmp yesc
nosc: cmp al,HT
jnz G016 ! jmp yeht ! G016:
cmp al,' '
jz G017 ! jmp noht ! G017:
yeht: call anch
cmp al,HT
jnz G018 ! jmp goht ! G018:
cmp al,' '
jnz G019 ! jmp goht ! G019:
call assm
jmp runrun
goht: call wrid ;byte to output stream
jmp yeht
noht: call inch ;byte from input stream
call wrid ;byte to output stream
cmp al,':'
jnz G020 ! jmp yeht ! G020:
call sepa ;z = separator
jnz G021 ! jmp yeht ! G021:
jmp noht
; %-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%
; Decode next character.
dnch: mov bx,(offset code) ;decoding table
dncr: call rbit ;read next bit
jc G022 ! jmp dncs ! G022: ;skip for 1, stay for 0
pushf ! inc bx ! popf
pushf ! inc bx ! popf
dncs: mov dl,[bx] ;get next offset
pushf ! inc bx ! popf
mov dh,[bx]
mov al,dh
cmp al,0FEH ;FEFF means [end]
jnz G023 ! jmp dnct ! G023:
or al,al
js G024 ! jmp dncu ! G024: ;p means new offset
mov al,dl ;m means complemented char
not al
stc
cmc
ret
dnct: stc ;flag [end] with carry bit
ret
; Calculate <code>+4*<offset>.
dncu: mov bx,(offset code) ;decoding table
add bx,dx
add bx,dx
add bx,dx
add bx,dx
jmp dncr
; Type CR, LF.
crlf: mov al,CR
call cona ;type character at console
mov al,LF
jmp cona ;type character at console
; Type .A86 text and accumulate checksum.
wrid: push bx
push dx
push cx
lahf ! xchg ah,al ! push ax ! xchg ah,al
mov ch,al
mov al,dens ;z/nz = un/squeezed
or al,al
jnz G025 ! jmp wrun ! G025:
mov bx,(offset cksm) ;checksum
mov al,[bx]
sub al,ch
mov [bx],al
pushf ! inc bx ! popf
mov al,[bx]
sbb al,0
mov [bx],al
wrun: mov al,ch
call cona
call wbyt ;send character to .A86 file
pop ax ! xchg ah,al ! sahf
pop cx
pop dx
pop bx
ret
; Upper case fold.
ucfo: cmp al,'a'
jnc G026 ! ret ! G026:
cmp al,'{'
jc G027 ! ret ! G027:
and al,5FH
ret
; Lower case fold.
lcin: call inch ;byte from input stream
lcfo: cmp al,'A'
jnc G028 ! ret ! G028:
cmp al,'['
jc G029 ! ret ! G029:
or al,20H
ret
; Send character in accumulator to console.
cona: push bx
push dx
push cx
lahf ! xchg ah,al ! push ax ! xchg ah,al
mov cl,2 ;(02) char to console
mov dl,al
int bdos
pop ax ! xchg ah,al ! sahf
pop cx
pop dx
pop bx
ret
; Send message to the console.
mssg: mov cl,9 ;(09) print buffer
int bdos ! ret
ourg: mov al,[bx]
or al,al
jnz G030 ! ret ! G030:
call wrid ;byte to output stream
pushf ! inc bx ! popf
jmp ourg ;phrase to output stream
; Verify the checksum.
chek: mov bx,cksm ;checksum
mov al,bh
or al,bl
jnz G031 ! jmp clof ! G031: ;close the file
mov cl,19 ;(13) delete file
mov dx,(offset FC86) ;.A86 FCB
int bdos
mov dx,(offset chno) ;'Checksum failure.'
call ferm ;final (error) message
; Close .A86 file.
clof: mov al,CO86 ;occupancy of .A86 buffer
cmp al,SZ86 ;size of .A86 buffer
jz G032 ! call wrdi ! G032:
mov cl,16 ;(10) close file
mov dx,(offset FC86) ;.A86 FCB
int bdos
cmp al,0FFH
mov dx,(offset nclo) ;'cannot close file'
jnz G033 ! jmp ferm ! G033: ;final (error) message
jmp exit
; Read one bit at a time.
rbit: push bx
mov bx,(offset roco) ;bit rotation counter
dec (byte ptr [bx])
jz G034 ! jmp rbiu ! G034:
mov (byte ptr [bx]),8
call rbyt ;fetch one byte from input stream
mov roby,al ;rotating byte
rbiu: mov al,roby ;rotating byte
rcr al,1
mov roby,al ;rotating byte
pop bx
ret
; Read one word.
rwor: call rbyt ;fetch one byte from input stream
lahf ! xchg ah,al ! push ax ! xchg ah,al
call rbyt ;fetch one byte from input stream
pop bx
mov bl,bh
mov bh,al
ret
; Fetch the next byte. The input buffer will be refreshed if it
; is necessary. For normal files, one byte will be extracted from
; the input buffer; for squeezed files, one byte will be decoded
; from the incoming bit stream and subtracted from the checksum.
inch: mov bx,(offset xait) ;z/nz = character not/waiting
mov al,[bx]
or al,al
jnz G035 ! jmp gech ! G035:
mov al,wach ;waiting character
mov (byte ptr [bx]),00
ret
anch: mov al,0FFH
mov xait,al ;z/nz = character not/waiting
call gech
mov wach,al ;waiting character
ret
gech: mov al,dens ;z/nz = un/squeezed
or al,al
jnz G036 ! jmp rbyt ! G036: ;fetch one byte
mov al,mult ;repeat factor
or al,al
jnz G037 ! jmp gusq ! G037:
dec al
mov mult,al ;repeat factor
mov al,lach
ret
gusq: call dnch
jc G038 ! jmp guss ! G038:
mov al,1AH
ret
guss: cmp al,090H
jnz G039 ! jmp gusu ! G039:
mov lach,al
ret
gusu: call dnch
or al,al
jz G040 ! jmp gusv ! G040:
mov al,090H
ret
gusv: dec al
dec al
mov mult,al ;repeat factor
mov al,lach
ret
; Read one byte, refill buffer as needed.
rbyt: push bx
mov bx,CO80 ;byte counter - input buffer
mov al,bl
or al,bh
jz G041 ! jmp rbyu ! G041:
call rdsk
mov bx,(offset BU80) ;.ASM buffer
mov PT80,bx ;byte pointer - input buffer
mov bx,(offset SZ80) ;size of .ASM file buffer
rbyu: pushf ! dec bx ! popf
mov CO80,bx ;byte counter - input buffer
mov bx,PT80 ;byte pointer - input buffer
mov al,[bx]
pushf ! inc bx ! popf
mov PT80,bx ;byte pointer - input buffer
pop bx
ret
; Insert byte in .A86 buffer.
wbyt: push bx
mov bx,(offset CO86) ;occupancy of .A86 buffer
dec (byte ptr [bx])
jz G042 ! jmp wbyy ! G042:
mov (byte ptr [bx]),SZ86 ;size of .A86 buffer
lahf ! xchg ah,al ! push ax ! xchg ah,al
mov bx,(offset BU86) ;.A86 buffer
mov PT86,bx ;pointer to .A86 buffer
call wrdi
call cbuz ;clear output buffer to zeroes
pop ax ! xchg ah,al ! sahf
wbyy: mov bx,PT86 ;pointer to .A86 buffer
mov [bx],al
pushf ! inc bx ! popf
mov PT86,bx ;pointer to .A86 buffer
pop bx
ret
; Send BU86 to disk.
wrdi: mov cl,26 ;(1A) set DMA address
mov dx,(offset BU86) ;.A86 buffer
int bdos
mov cl,21 ;(15) write one record
mov dx,(offset FC86) ;.A86 DCB
int bdos
cmp al,00H
mov dx,(offset werr) ;'disk write'
jz G043 ! jmp ferm ! G043: ;final (error) message
ret
rdsk: push bx
push dx
push cx
mov cl,26 ;(1A) set DMA address
mov dx,(offset BU80) ;.ASM buffer
int bdos
mov cl,20 ;(14) read one record
mov dx,(offset FC80) ;.ASM FCB
int bdos
pop cx
pop dx
pop bx
ret
; Fill BU86 with zeroes.
cbuz: xor al,al
mov ch,1 ;one sector in buffer
mov bx,(offset BU86) ;.A86 buffer
cbuy: mov cl,tsiz ;record size
cbux: mov [bx],al
pushf ! inc bx ! popf
dec cl
jz G044 ! jmp cbux ! G044:
dec ch
jz G045 ! jmp cbuy ! G045:
ret
; Block fill with C B's starting at (HL).
fiuc: mov [bx],ch
pushf ! inc bx ! popf
dec cl
jz G046 ! jmp fiuc ! G046: ;block fill
ret
miuc: xchg dx,bx ! mov al,[bx] ! xchg dx,bx
mov [bx],al
pushf ! inc bx ! popf
pushf ! inc dx ! popf
dec ch
jz G047 ! jmp miuc ! G047:
ret
; Assemble the 8080 source code.
assm: call alfa
jmp opco
; Read an alpha field by ignoring leading separators,
; storing letters in registers C,D,E, and terminating
; reading when a separator is again encountered. All
; fields are held to three letters, so that the only
; letters in a chain that are stored are the first,
; second, and last.
alfa: mov dx,2020H
ala: call lcin
call sepa ;z = separator
jnz G048 ! jmp ala ! G048:
mov cl,al
call lcin
call sepa ;z = separator
jnz G049 ! ret ! G049:
mov dh,al
alb: call lcin
call sepa ;z = separator
jnz G050 ! ret ! G050:
mov dl,al
jmp alb
; Read an alpha field with the intention of keeping only
; the last letter in the field. Otherwise the same rules
; apply as in the subroutine alfa: leading separators
; are ignored, trailing separators terminate.
beta: call lcin
call sepa ;z = separator
jnz G051 ! jmp beta ! G051:
bet: mov ch,al
call lcin
call sepa ;z = separator
jz G052 ! jmp bet ! G052:
mov sepr,al
mov al,ch
ret
; Test for separators or delimiters. The character to be
; tested is in the accumulator, where it remains. A zero
; flag means it was a separator.
sepa: cmp al,' '
jnz G053 ! ret ! G053:
cmp al,','
jnz G054 ! ret ! G054:
cmp al,HT
jnz G055 ! ret ! G055:
cmp al,CR
jnz G056 ! ret ! G056:
cmp al,LF
ret
; Locate the operation codes. A simple linear search is
; made of some sixty mnemonics, grouping them mostly in
; sets of eight because their position within an octet
; translates directly into a source or destination field
; in the 2-3-3 decomposition of INTEL 8080 opcodes.
opco: mov ch,12
mov bx,(offset T4) ;Quadrant 0 with minor modifications
call mnem
js G057 ! jmp Q0 ! G057:
mov ch,01
mov bx,(offset T0) ;Quadrant 1: interregister movements
call mnem
js G058 ! jmp Q1 ! G058:
mov ch,08
mov bx,(offset T1) ;Quadrant 3: arithmetic-logical
call mnem
js G059 ! jmp Q2 ! G059:
mov ch,08
mov bx,(offset T2) ;Quadrant 2, column 6: immediate
call mnem
js G060 ! jmp B6 ! G060:
mov ch,9
mov bx,(offset T4@1) ;All the one-byte sporadic opcodes
call mnem
js G061 ! jmp gg ! G061:
mov ch,2
mov bx,(offset T4@2) ;All the two-byte sporadic opcodes
call mnem
js G062 ! jmp tt ! G062:
mov ch,4
mov bx,(offset T4@3) ;All the three byte sporadic opcodes
call mnem
js G063 ! jmp uu ! G063:
mov ch,2
mov bx,(offset T5)
call mnem
js G064 ! jmp vv ! G064:
mov ch,08
mov bx,(offset T3) ;Quadrant 0, column 7: accumulator
call mnem
js G065 ! jmp A7 ! G065:
mov al,cl
cmp al,'r'
jnz G066 ! jmp B0 ! G066: ;Quadrant 3, column 0: returns
cmp al,'j'
jnz G067 ! jmp B2 ! G067: ;Quadrant 3, column 2: jumps
cmp al,'c'
jnz G068 ! jmp B4 ! G068: ;Quadrant 3, column 4: calls
mov ch,6
mov bx,(offset T7) ;Assembler directives
call mnem
js G069 ! jmp qd ! G069:
jmp none ;error - unrecognizable code
Q0: call juta
dw A0 ;pop pair
dw A3 ;lxi pair,addr
dw A2 ;stax pair - beware - only b, d legal
dw A1 ;inx pair
dw A4 ;inr register
dw A4 ;dcr register
dw A4 ;mvi register,data
dw B7 ;rst digit in opcode
dw A0 ;push pair
dw A0 ;dad pair
dw A2 ;ldax pair - beware - only b, d legal
dw A1 ;dcx pair
A0: lahf ! xchg ah,al ! push ax ! xchg ah,al
call beta
cmp al,'w'
jnz G070 ! jmp A0@1 ! G070:
pop cx
lahf ! xchg ah,al ! push ax ! xchg ah,al
mov al,ch
mov dx,(offset QZ86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
pop ax ! xchg ah,al ! sahf
call pair ;identify register pair
mov al,[bx]
call wrid ;byte to output stream
pushf ! inc bx ! popf
mov al,[bx]
call wrid ;byte to output stream
jmp rest ;comment to output stream
A0@1: pop ax ! xchg ah,al ! sahf
or al,al
jnz G071 ! jmp A0@2 ! G071:
mov bx,(offset QZ86@C)
jmp A0@3
A0@2: mov bx,(offset QZ86@D)
A0@3: call ourg ;phrase to output stream
jmp rest ;comment to output stream
A1: mov dx,(offset QZ86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
push bx
call beta
call pair ;identify register pair
mov al,[bx]
call wrid ;byte to output stream
pushf ! inc bx ! popf
mov al,[bx]
call wrid ;byte to output stream
pop bx
pushf ! inc bx ! popf
call ourg ;phrase to output stream
jmp rest ;comment to output stream
A2: mov dx,(offset QZ86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
push bx
call beta
call pair ;identify register pair
push bx
mov al,[bx]
call wrid ;byte to output stream
pushf ! inc bx ! popf
mov al,[bx]
call wrid ;byte to output stream
pop bx
xchg sp,bp ! xchg bx,[bp] ! xchg sp,bp
pushf ! inc bx ! popf
call ourg ;phrase to output stream
xchg sp,bp ! xchg bx,[bp] ! xchg sp,bp
mov al,[bx]
call wrid ;byte to output stream
pushf ! inc bx ! popf
mov al,[bx]
call wrid ;byte to output stream
pop bx
pushf ! inc bx ! popf
call ourg ;phrase to output stream
jmp resu ;rest of line to output
A3: mov dx,(offset QZ86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
push bx
call beta
call pair ;identify register pair
mov al,[bx]
call wrid ;byte to output stream
pushf ! inc bx ! popf
mov al,[bx]
call wrid ;byte to output stream
pop bx
pushf ! inc bx ! popf
call ourg ;phrase to output stream
push bx
call addq ;read address field
pop bx
pushf ! inc bx ! popf
call ourg ;phrase to output stream
jmp resu ;rest of line to output
A4: mov dx,(offset QZ86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
call sreg
mov al,sepr
call wrid ;byte to output stream
jmp resu ;rest of line to output
A7: mov dx,(offset AC86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
jmp rest ;comment to output stream
Q1: mov bx,(offset MO86)
call ourg ;phrase to output stream
call rreg ;identify register
mov al,','
call wrid ;byte to output stream
call rreg ;identify register
jmp rest ;comment to output stream
Q2: mov bl,al
mov bh,0
add bx,bx
add bx,bx
add bx,bx
mov dx,(offset IM86)
add bx,dx
call ourg ;phrase to output stream
call rreg ;identify register
jmp resu ;rest of line to output
gg: mov dx,(offset NB86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
jmp rest ;comment to output stream
tt: mov dx,(offset WB86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
jmp resu ;rest of line to output
uu: mov dx,(offset HB86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
jmp resu ;rest of line to output
vv: mov dx,(offset IB86)
call meta ;locate numbered phrase
call ourg ;phrase to output stream
push bx
call addq ;read address field
pop bx
pushf ! inc bx ! popf
call ourg ;phrase to output stream
jmp rest ;comment to output stream
B0: call bb
mov bx,(offset CR86)
call ourg ;phrase to output stream
jmp ff
B2: call bb
mov bx,(offset CJ86)
call ourg ;phrase to output stream
call addq ;read address field
jmp ff
B4: call bb
mov bx,(offset CC86)
call ourg ;phrase to output stream
call addq ;read address field
jmp ff
bb: mov cl,' '
mov ch,08
mov bx,(offset T6)
call mnem
jns G072 ! jmp none ! G072: ;error - unrecognizable code
mov bl,al
mov dl,al
mov bh,0
mov dh,0
add bx,bx
add bx,bx
add bx,dx
mov dx,(offset CN86)
add bx,dx
call ourg ;phrase to output stream
call incr ;increment gensym
mov bx,(offset gsym) ;gensym #
call ourg ;phrase to output stream
mov bx,(offset excl)
jmp ourg ;phrase to output stream
ff: mov bx,(offset excl)
call ourg ;phrase to output stream
mov bx,(offset gsym) ;gensym #
call ourg ;phrase to output stream
mov al,':'
call wrid ;byte to output stream
jmp rest ;comment to output stream
B6: mov bl,al
mov bh,0
add bx,bx
add bx,bx
add bx,bx
mov dx,(offset IM86)
add bx,dx
call ourg ;phrase to output stream
jmp resu ;rest of line to output
B7: mov bx,(offset QZ86@7)
call ourg ;phrase to output stream
jmp resu ;rest of line to output
qd: call juta
dw D0 ;data byte
dw D1 ;data word
dw D2 ;data space
dw D3 ;equivalence
dw D4 ;origin
dw D5 ;end
D0: mov bx,(offset DB86)
call ourg ;phrase to output stream
jmp resu ;rest of line to output
D1: mov bx,(offset DW86)
call ourg ;phrase to output stream
jmp resu ;rest of line to output
D2: call inch ;byte from input stream
cmp al,HT
jnz G073 ! jmp D2 ! G073:
cmp al,' '
jnz G074 ! jmp D2 ! G074:
cmp al,'2'
jnz G075 ! jmp D2@0 ! G075:
lahf ! xchg ah,al ! push ax ! xchg ah,al
mov bx,(offset RB86)
call ourg ;phrase to output stream
pop ax ! xchg ah,al ! sahf
call wrid ;byte to output stream
jmp resu ;rest of line to output
D2@0: call inch ;byte from input stream
call sepa ;z = separator
jnz G076 ! jmp D2@1 ! G076:
lahf ! xchg ah,al ! push ax ! xchg ah,al
mov bx,(offset RB86)
call ourg ;phrase to output stream
mov al,'2'
call wrid ;byte to output stream
pop ax ! xchg ah,al ! sahf
call wrid ;byte to output stream
jmp resu ;rest of line to output
D2@1: mov bx,(offset RW86)
call ourg ;phrase to output stream
jmp resu ;rest of line to output
D3: mov bx,(offset EQ86)
call ourg ;phrase to output stream
jmp rest ;comment to output stream
D4: mov bx,(offset OR86)
call ourg ;phrase to output stream
jmp rest ;comment to output stream
D5: mov bx,(offset EN86)
call ourg ;phrase to output stream
call rest ;comment to output stream
jmp clof
; The only errors recognized are unintelligible registers
; or mnemonics.
none: mov bx,(offset ER86)
call ourg ;phrase to output stream
jmp rest ;comment to output stream
; Finish out a line.
; rest for comments
; resu for parameters
rest: call inch ;byte from input stream
cmp al,HT
jnz G077 ! jmp rest ! G077: ;comment to output stream
cmp al,' '
jnz G078 ! jmp rest ! G078: ;comment to output stream
cmp al,CR
jnz G079 ! jmp rest ! G079: ;comment to output stream
cmp al,LF
jz G080 ! jmp ress ! G080:
mov al,CR
call wrid ;byte to output stream
mov al,LF
jmp wrid ;byte to output stream
ress: lahf ! xchg ah,al ! push ax ! xchg ah,al
mov al,HT
call wrid ;byte to output stream
pop ax ! xchg ah,al ! sahf
call wrid ;byte to output stream
resu: call inch ;byte from input stream
cmp al,CR
jnz G081 ! jmp resu ! G081: ;rest of line to output
cmp al,LF
jnz G082 ! jmp resv ! G082:
call wrid ;byte to output stream
jmp resu ;rest of line to output
resv: mov al,CR
call wrid ;byte to output stream
mov al,LF
jmp wrid ;byte to output stream
; Read an address or other two-byte field.
addq: call inch ;byte from input stream
cmp al,HT
jnz G083 ! jmp addq ! G083: ;read address field
cmp al,' '
jnz G084 ! jmp addq ! G084: ;read address field
addr: call wrid ;byte to output stream
call inch ;byte from input stream
call sepa ;z = separator
jz G085 ! jmp addr ! G085:
ret
; Increment gensym counter.
incr: mov bx,(offset gsym+3)
incs: mov al,[bx]
or al,30H
inc al
mov [bx],al
cmp al,':'
jz G086 ! ret ! G086:
mov (byte ptr [bx]),'0'
pushf ! dec bx ! popf
jmp incs
; Find the address of the nth message, when DE points to the
; message address table and A is the number of the message.
meta: mov bl,al
mov bh,0
add bx,bx
add bx,dx
mov dl,[bx]
pushf ! inc bx ! popf
mov dh,[bx]
xchg dx,bx
ret
; Jump to the nth address in the table following the call
; to juta, where n is located in the accumulator. The
; value of the accumulator is conserved in register c.
juta: pop bx
mov cl,al
add al,al
add al,bl
mov bl,al
mov al,bh
adc al,00H
mov bh,al
mov al,cl
mov dl,[bx]
pushf ! inc bx ! popf
mov dh,[bx]
xchg dx,bx
jmp bx
; Find numerical equivalents for register designations.
; Source registers are reported at their true value, but
; destination registers are multiplied by eight to have
; their value positioned correctly for its field.
rreg: call beta
mov ch,08H
mov bx,(offset tr)
call regi ;identify register
jns G087 ! jmp none ! G087: ;error - unrecognizable code
mov bx,(offset RGEM)
cmp al,06
jnz G088 ! jmp ourg ! G088: ;phrase to output stream
mov bx,(offset RG86)
mov dl,al
mov dh,0
add bx,dx
add bx,dx
add bx,dx
jmp ourg ;phrase to output stream
sreg: call beta
mov ch,08H
mov bx,(offset tr)
call regi ;identify register
jns G089 ! jmp none ! G089: ;error - unrecognizable code
mov bx,(offset RGEN)
cmp al,06
jnz G090 ! jmp ourg ! G090: ;phrase to output stream
mov bx,(offset RG86)
mov dl,al
mov dh,0
add bx,dx
add bx,dx
add bx,dx
jmp ourg ;phrase to output stream
; Find numerical equivalents for register pair symbols.
; They always left-pack their destination field.
pair: mov ch,05H
mov bx,(offset tp)
call regi ;identify register
jns G091 ! jmp none ! G091: ;error - unrecognizable code
mov bl,al
mov bh,0
add bx,bx
mov dx,(offset PA86)
add bx,dx
ret
; Search a list of bytes whose origin is contained in
; in HL to find the one, if any, which matches the
; accumulator. The length of the list in is B on entry;
; on exit A contains either the position or FF if no
; match was found.
regi: pushf ! dec bx ! popf
cmp al,[bx]
jnz G092 ! jmp reg ! G092:
dec ch
jz G093 ! jmp regi ! G093: ;identify register
reg: xor al,al
dec ch
or al,ch
ret
; Search a table of three-letter mnemonics to find the
; code contained in registers C,D,E. Enter with the
; table origin in pair HL, the table size N in the
; accumulator. On exit the accumulator will contain
; either the position, ranging between 0 and N-1, of
; the item in the table, or else FF(hex) if it was not
; found.
mnem: pushf ! dec bx ! popf
mov al,[bx]
cmp al,dl
jz G094 ! jmp mnb ! G094:
pushf ! dec bx ! popf
mov al,[bx]
cmp al,dh
jz G095 ! jmp mnc ! G095:
pushf ! dec bx ! popf
mov al,[bx]
sub al,cl
jz G096 ! jmp mnd ! G096:
mna: dec ch
or al,ch
ret
mnb: pushf ! dec bx ! popf
mnc: pushf ! dec bx ! popf
mnd: dec ch
jz G097 ! jmp mnem ! G097:
jmp mna
; Table of mnemonics grouped by octets and dodecuplets.
db 'bcdehlma'
tr db 'bdhpw'
tp db 'mov'
T0 db 'add','adc','sub','sbb'
db 'ana','xra','ora','cmp'
T1 db 'adi','aci','sui','sbi'
db 'ani','xri','ori','cpi'
T2 db 'rlc','rrc','ral','rar'
db 'daa','cma','stc','cmc'
T3 db 'pop','lxi','stx','inx'
db 'inr','dcr','mvi','rst'
db 'puh','dad','ldx','dcx'
T4 db 'nop','ret','pcl','spl'
db 'xtl','xcg','di ','ei '
db 'hlt'
T4@1 db 'out','in '
T4@2 db 'jmp','cal','lda','lhd'
T4@3 db 'sta','shd'
T5 db ' nz',' z ',' nc',' c '
db ' po',' pe',' p ',' m '
T6 db 'db ','dw ','ds ','equ','org','end'
T7 rb 0
RG86 db 'ch',00
db 'cl',00
db 'dh',00
db 'dl',00
db 'bh',00
db 'bl',00
db '..',00
db 'al',00
RGEM db '[bx]',00
RGEN db '(byte ptr [bx])',0
PA86 db 'cx'
db 'dx'
db 'bx'
db 'sp'
db 'ax'
QZ86 dw QZ86@0
dw QZ86@1
dw QZ86@2
dw QZ86@3
dw QZ86@4
dw QZ86@5
dw QZ86@6
dw QZ86@7
dw QZ86@8
dw QZ86@9
dw QZ86@A
dw QZ86@B
QZ86@0 db 'pop',HT,0
QZ86@1 db 'mov',HT,0,',(offset ',0,')',HT,0
QZ86@2 db 'xchg ',0,',bx ! mov [bx],al ! xchg ',0,',bx',0
QZ86@3 db 'pushf ! inc ',0,' ! popf',HT,0
QZ86@4 db 'inc',HT,0
QZ86@5 db 'dec',HT,0
QZ86@6 db 'mov',HT,0
QZ86@7 db 'call',HT,'offset 8*',0
QZ86@8 db 'push',HT,0
QZ86@9 db 'add',HT,'bx,',0
QZ86@A db 'xchg ',0,',bx ! mov al,[bx] ! xchg ',0,',bx',0
QZ86@B db 'pushf ! dec ',0,' ! popf',HT,0
QZ86@C db 'lahf ! xchg ah,al ! push ax ! xchg ah,al',0
QZ86@D db 'pop ax ! xchg ah,al ! sahf',0
MO86 db 'mov',HT,00
IM86 db 'add',HT,'al,',00
db 'adc',HT,'al,',00
db 'sub',HT,'al,',00
db 'sbb',HT,'al,',00
db 'and',HT,'al,',00
db 'xor',HT,'al,',00
db 'or',HT,'al,',00,00
db 'cmp',HT,'al,',00
AC86 dw AC86@0
dw AC86@1
dw AC86@2
dw AC86@3
dw AC86@4
dw AC86@5
dw AC86@6
dw AC86@7
AC86@0 db 'rol',HT,'al,1',0
AC86@1 db 'ror',HT,'al,1',0
AC86@2 db 'rcl',HT,'al,1',0
AC86@3 db 'rcr',HT,'al,1',0
AC86@4 db 'daa',0
AC86@5 db 'not',HT,'al',0
AC86@6 db 'stc',0
AC86@7 db 'cmc',0
NB86 dw NB86@0
dw NB86@1
dw NB86@2
dw NB86@3
dw NB86@4
dw NB86@5
dw NB86@6
dw NB86@7
dw NB86@8
NB86@0 db 'nop',0
NB86@1 db 'ret',0
NB86@2 db 'jmp',HT,'bx',0
NB86@3 db 'mov',HT,'sp,bx',0
NB86@4 db 'xchg sp,bp ! xchg bx,[bp] ! xchg sp,bp',0
NB86@5 db 'xchg',HT,'dx,bx',0
NB86@6 db 'di',0
NB86@7 db 'ei',0
NB86@8 db 'hlt',0
WB86 dw WB86@0
dw WB86@1
WB86@0 db 'out',HT,'al,',0
WB86@1 db 'in',HT,'al,',0
HB86 dw HB86@0
dw HB86@1
dw HB86@2
dw HB86@3
HB86@0 db 'jmp',HT,0
HB86@1 db 'call',HT,0
HB86@2 db 'mov',HT,'al,',0
HB86@3 db 'mov',HT,'bx,',0
IB86 dw IB86@0
dw IB86@1
IB86@0 db 'mov',HT,0,',al',0
IB86@1 db 'mov',HT,0,',bx',0
CN86 db 'jz ',0,0
db 'jnz ',00
db 'jc ',0,0
db 'jnc ',00
db 'jpe ',00
db 'jpo ',00
db 'js ',0,0
db 'jns ',00
excl db ' ! ',00
CR86 db 'ret',0
CJ86 db 'jmp ',0
CC86 db 'call ',0
DB86 db 'db',HT,0
DW86 db 'dw',HT,0
RB86 db 'rb',HT,0
RW86 db 'rw',HT,'1',0
EQ86 db 'equ',HT,0
OR86 db 'org',HT,0
EN86 db 'end',0
ER86 db '[-error-]',0
logo db ' 80T86/ICUAP',CR,LF
db 'Universidad Autonoma de Puebla',CR,LF
db ' August 28, 1984',CR,LF,'$'
tuto db '80T86 will translate .ASM files for the Intel 8080',CR,LF
db 'into .A86 files for the Intel 8086.',CR,LF
db CR,LF
db ' 80T86 [X:]FILE[.XXX]',CR,LF
db CR,LF
db 'will read [X:]FILE[.XXX] to produce [X:]FILE.A86.',CR,LF
db 'All operation codes and the assembler directives',CR,LF
db 'db, dw, ds, equ, org, end will be translated, but',CR,LF
db 'many constructions will have to be transformed by',CR,LF
db 'hand afterwards. These include <call BDOS>, colons',CR,LF
db 'in the labels of db''s, dw''s and ds''s, labels which',CR,LF
db 'conflict with Intel 8086 opcodes or directives, dollar',CR,LF
db 'signs which form part of labels, asolute addresses',CR,LF
db 'such as CP/M''s file control block, and so on. The',CR,LF
db 'source file may be squeezed.',CR,LF
db '$'
werr db CR,LF,'Disk write error.$'
nfil db CR,LF,'Requested file not present.$'
yexi db CR,LF,'.A86 file already exists.$'
ntab db CR,LF,'Insufficient space for dictionary.$'
nasm db CR,LF,'Not an .ASM file.$'
chno db CR,LF,'Checksum failure.$'
nopn db CR,LF,'Can''t open source.$'
nodi db CR,LF,'Disk or Directory full.$'
nclo db CR,LF,'Cannot close file.$'
gsym db 'G000',00
FC86 rb 21H ;.A86 FCB
CO86 rb 1 ;occupancy of .A86 buffer
PT86 rw 1 ;pointer to .A86 buffer
BU86 rb SZ86 ;.A86 buffer
lach rb 1 ;last character typed
sepr rb 1 ;last separator read
roco rb 1 ;rotating bit counter
roby rb 1 ;rotating byte
dens rb 1 ;z/nz = un/squeezed
mult rb 1 ;repeat factor
xait rb 1 ;z/nz = character not/waiting
wach rb 1 ;waiting character
CO80 rw 1 ;byte counter - input buffer
PT80 rw 1 ;byte pointer - input buffer
cksm rw 1 ;checksum
code rb 4*csiz ;decoding table
stak rw 1 ;stackend
end